/* @internal */
名域 ts {
    导出 接口 CommentWriter {
        reset(): 无值;
        setSourceFile(源文件: 源文件_): 无值;
        setWriter(writer: 输出文本作者_): 无值;
        emitNodeWithComments(hint: 输出提示_, n: 节点_, emitCallback: (hint: 输出提示_, n: 节点_) => 无值): 无值;
        emitBodyWithDetachedComments(n: 节点_, detachedRange: 文本范围_, emitCallback: (n: 节点_) => 无值): 无值;
        emitTrailingCommentsOfPosition(首位: 数字, prefixSpace?: 真假): 无值;
        emitLeadingCommentsOfPosition(首位: 数字): 无值;
    }

    导出 函数 createCommentWriter(printerOptions: 打印机选项_, emitPos: ((首位: 数字) => 无值) | 未定): CommentWriter {
        常量 extendedDiagnostics = printerOptions.extendedDiagnostics;
        常量 newLine = 获取新行字符(printerOptions);
        变量 writer: 输出文本作者_;
        变量 containerPos = -1;
        变量 containerEnd = -1;
        变量 declarationListContainerEnd = -1;
        变量 currentSourceFile: 源文件_;
        变量 currentText: 文字;
        变量 currentLineMap: 只读数组_<数字>;
        变量 detachedCommentsInfo: { nodePos: 数字, detachedCommentEndPos: 数字}[];
        变量 hasWrittenComment = 为假;
        变量 disabled: 真假 = !!printerOptions.removeComments;

        返回 {
            reset,
            setWriter,
            setSourceFile,
            emitNodeWithComments,
            emitBodyWithDetachedComments,
            emitTrailingCommentsOfPosition,
            emitLeadingCommentsOfPosition,
        };

        函数 emitNodeWithComments(hint: 输出提示_, n: 节点_, emitCallback: (hint: 输出提示_, n: 节点_) => 无值) {
            如果 (disabled) {
                emitCallback(hint, n);
                返回;
            }

            如果 (n) {
                hasWrittenComment = 为假;

                常量 输出节点 = n.输出节点;
                常量 emitFlags = 输出节点 && 输出节点.标志;
                常量 { 首位, 尾位 } = 输出节点 && 输出节点.注释范围 || n;
                如果 ((首位 < 0 && 尾位 < 0) || (首位 === 尾位)) {
                    // Both 首位 and 尾位 are synthesized, so just emit the n without 注释组.
                    emitNodeWithSynthesizedComments(hint, n, 输出节点!, emitFlags!, emitCallback);
                }
                否则 {
                    如果 (extendedDiagnostics) {
                        性能.标记('preEmitNodeWithComment');
                    }

                    常量 isEmittedNode = n.种类 !== 语法_.不输出语句_;
                    // We have to explicitly check that the n is JsxText because if the compilerOptions.jsx is 'preserve' we will not do any transformation.
                    // It is expensive to walk entire tree just to set one 种类 of n to have no 注释组.
                    常量 skipLeadingComments = 首位 < 0 || (emitFlags! & 输出标志_.NoLeadingComments) !== 0;
                    常量 skipTrailingComments = 尾位 < 0 || (emitFlags! & 输出标志_.NoTrailingComments) !== 0;

                    // Emit leading 注释组 if the position is not synthesized and the n
                    // has not opted out from emitting leading 注释组.
                    如果 (!skipLeadingComments) {
                        emitLeadingComments(首位, isEmittedNode);
                    }

                    // Save 当前 container 状态 on the stack.
                    常量 savedContainerPos = containerPos;
                    常量 savedContainerEnd = containerEnd;
                    常量 savedDeclarationListContainerEnd = declarationListContainerEnd;

                    如果 (!skipLeadingComments) {
                        containerPos = 首位;
                    }

                    如果 (!skipTrailingComments) {
                        containerEnd = 尾位;
                    }

                    如果 (extendedDiagnostics) {
                        性能.度量('commentTime', 'preEmitNodeWithComment');
                    }

                    emitNodeWithSynthesizedComments(hint, n, 输出节点!, emitFlags!, emitCallback);

                    如果 (extendedDiagnostics) {
                        性能.标记('postEmitNodeWithComment');
                    }

                    // Restore previous container 状态.
                    containerPos = savedContainerPos;
                    containerEnd = savedContainerEnd;
                    declarationListContainerEnd = savedDeclarationListContainerEnd;

                    // Emit trailing 注释组 if the position is not synthesized and the n
                    // has not opted out from emitting leading 注释组 and is an emitted n.
                    如果 (!skipTrailingComments && isEmittedNode) {
                        emitTrailingComments(尾位);
                    }

                    如果 (extendedDiagnostics) {
                        性能.度量('commentTime', 'postEmitNodeWithComment');
                    }
                }
            }
        }

        函数 emitNodeWithSynthesizedComments(hint: 输出提示_, n: 节点_, 输出节点: 输出节点_, emitFlags: 输出标志_, emitCallback: (hint: 输出提示_, n: 节点_) => 无值) {
            常量 leadingComments = 输出节点 && 输出节点.前导注释;
            如果 (某些(leadingComments)) {
                如果 (extendedDiagnostics) {
                    性能.标记('preEmitNodeWithSynthesizedComments');
                }

                循环执行(leadingComments, emitLeadingSynthesizedComment);

                如果 (extendedDiagnostics) {
                    性能.度量('commentTime', 'preEmitNodeWithSynthesizedComments');
                }
            }

            emitNodeWithNestedComments(hint, n, emitFlags, emitCallback);

            常量 trailingComments = 输出节点 && 输出节点.尾随注释;
            如果 (某些(trailingComments)) {
                如果 (extendedDiagnostics) {
                    性能.标记('postEmitNodeWithSynthesizedComments');
                }

                循环执行(trailingComments, emitTrailingSynthesizedComment);

                如果 (extendedDiagnostics) {
                    性能.度量('commentTime', 'postEmitNodeWithSynthesizedComments');
                }
            }
        }

        函数 emitLeadingSynthesizedComment(注释: 合成注释_) {
            如果 (注释.种类 === 语法_.单行注释杂项_) {
                writer.writeLine();
            }
            writeSynthesizedComment(注释);
            如果 (注释.有尾随新行 || 注释.种类 === 语法_.单行注释杂项_) {
                writer.writeLine();
            }
            否则 {
                writer.write(' ');
            }
        }

        函数 emitTrailingSynthesizedComment(注释: 合成注释_) {
            如果 (!writer.isAtStartOfLine()) {
                writer.write(' ');
            }
            writeSynthesizedComment(注释);
            如果 (注释.有尾随新行) {
                writer.writeLine();
            }
        }

        函数 writeSynthesizedComment(注释: 合成注释_) {
            常量 文本 = formatSynthesizedComment(注释);
            常量 行词典 = 注释.种类 === 语法_.多行注释杂项_ ? 计算行开始(文本) : 未定;
            写注释范围(文本, 行词典!, writer, 0, 文本.长度, newLine);
        }

        函数 formatSynthesizedComment(注释: 合成注释_) {
            返回 注释.种类 === 语法_.多行注释杂项_
                ? `/*${注释.文本}*/`
                : `//${注释.文本}`;
        }

        function emitNodeWithNestedComments(hint: 输出提示_, n: 节点_, emitFlags: 输出标志_, emitCallback: (hint: 输出提示_, n: 节点_) => 无值) {
            如果 (emitFlags & 输出标志_.NoNestedComments) {
                disabled = 为真;
                emitCallback(hint, n);
                disabled = 为假;
            }
            否则 {
                emitCallback(hint, n);
            }
        }

        函数 emitBodyWithDetachedComments(n: 节点_, detachedRange: 文本范围_, emitCallback: (n: 节点_) => 无值) {
            如果 (extendedDiagnostics) {
                性能.标记('preEmitBodyWithDetachedComments');
            }

            常量 { 首位, 尾位 } = detachedRange;
            常量 emitFlags = getEmitFlags(n);
            常量 skipLeadingComments = 首位 < 0 || (emitFlags! & 输出标志_.NoLeadingComments) !== 0;
            常量 skipTrailingComments = disabled || 尾位 < 0 || (emitFlags! & 输出标志_.NoTrailingComments) !== 0;

            如果 (!skipLeadingComments) {
                emitDetachedCommentsAndUpdateCommentsInfo(detachedRange);
            }

            如果 (extendedDiagnostics) {
                性能.度量('commentTime', 'preEmitBodyWithDetachedComments');
            }

            如果 (emitFlags! & 输出标志_.NoNestedComments && !disabled) {
                disabled = 为真;
                emitCallback(n);
                disabled = 为假;
            }
            否则 {
                emitCallback(n);
            }

            如果 (extendedDiagnostics) {
                性能.标记('beginEmitBodyWithDetachedCommetns');
            }

            如果 (!skipTrailingComments) {
                emitLeadingComments(detachedRange.尾位, /*isEmittedNode*/ 为真);
                如果 (hasWrittenComment && !writer.isAtStartOfLine()) {
                    writer.writeLine();
                }
            }

            如果 (extendedDiagnostics) {
                性能.度量('commentTime', 'beginEmitBodyWithDetachedCommetns');
            }
        }

        函数 emitLeadingComments(首位: 数字, isEmittedNode: 真假) {
            hasWrittenComment = 为假;

            如果 (isEmittedNode) {
                forEachLeadingCommentToEmit(首位, emitLeadingComment);
            }
        }

        函数 emitLeadingComment(commentPos: 数字, commentEnd: 数字, 种类: 语法_, 有尾随新行: 真假, rangePos: 数字) {
            如果 (!hasWrittenComment) {
                输出位置的新行之的前前导注释(currentLineMap, writer, rangePos, commentPos);
                hasWrittenComment = 为真;
            }

            // Leading 注释组 are emitted at /*leading comment1 */空格_/*leading 注释*/空格_
            如果 (emitPos) emitPos(commentPos);
            写注释范围(currentText, currentLineMap, writer, commentPos, commentEnd, newLine);
            如果 (emitPos) emitPos(commentEnd);

            如果 (有尾随新行) {
                writer.writeLine();
            }
            否则 如果 (种类 === 语法_.多行注释杂项_) {
                writer.write(' ');
            }
        }

        函数 emitLeadingCommentsOfPosition(首位: 数字) {
            如果 (disabled || 首位 === -1) {
                返回;
            }

            emitLeadingComments(首位, /*isEmittedNode*/ 为真);
        }

        函数 emitTrailingComments(首位: 数字) {
            forEachTrailingCommentToEmit(首位, emitTrailingComment);
        }

        函数 emitTrailingComment(commentPos: 数字, commentEnd: 数字, _kind: 语法_, 有尾随新行: 真假) {
            // trailing 注释组 are emitted at 空格_/*trailing comment1 */空格_/*trailing comment2*/
            如果 (!writer.isAtStartOfLine()) {
                writer.write(' ');
            }

            如果 (emitPos) emitPos(commentPos);
            写注释范围(currentText, currentLineMap, writer, commentPos, commentEnd, newLine);
            如果 (emitPos) emitPos(commentEnd);

            如果 (有尾随新行) {
                writer.writeLine();
            }
        }

        函数 emitTrailingCommentsOfPosition(首位: 数字, prefixSpace?: 真假) {
            如果 (disabled) {
                返回;
            }

            如果 (extendedDiagnostics) {
                性能.标记('beforeEmitTrailingCommentsOfPosition');
            }

            forEachTrailingCommentToEmit(首位, prefixSpace ? emitTrailingComment : emitTrailingCommentOfPosition);

            如果 (extendedDiagnostics) {
                性能.度量('commentTime', 'beforeEmitTrailingCommentsOfPosition');
            }
        }

        函数 emitTrailingCommentOfPosition(commentPos: 数字, commentEnd: 数字, _kind: 语法_, 有尾随新行: 真假) {
            // trailing 注释组 of a position are emitted at /*trailing comment1 */空格_/*trailing 注释*/空格_

            如果 (emitPos) emitPos(commentPos);
            写注释范围(currentText, currentLineMap, writer, commentPos, commentEnd, newLine);
            如果 (emitPos) emitPos(commentEnd);

            如果 (有尾随新行) {
                writer.writeLine();
            }
            否则 {
                writer.write(' ');
            }
        }

        函数 forEachLeadingCommentToEmit(首位: 数字, cb: (commentPos: 数字, commentEnd: 数字, 种类: 语法_, 有尾随新行: 真假, rangePos: 数字) => 无值) {
            // Emit the leading 注释组 only if the container's 首位 doesn't match because the container should take care of emitting these 注释组
            如果 (containerPos === -1 || 首位 !== containerPos) {
                如果 (hasDetachedComments(首位)) {
                    forEachLeadingCommentWithoutDetachedComments(cb);
                }
                否则 {
                    循环前导注释范围(currentText, 首位, cb, /*状态*/ 首位);
                }
            }
        }

        函数 forEachTrailingCommentToEmit(尾位: 数字, cb: (commentPos: 数字, commentEnd: 数字, 种类: 语法_, 有尾随新行: 真假) => 无值) {
            // Emit the trailing 注释组 only if the container's 尾位 doesn't match because the container should take care of emitting these 注释组
            如果 (containerEnd === -1 || (尾位 !== containerEnd && 尾位 !== declarationListContainerEnd)) {
                循环尾随注释范围(currentText, 尾位, cb);
            }
        }

        函数 reset() {
            currentSourceFile = 未定!;
            currentText = 未定!;
            currentLineMap = 未定!;
            detachedCommentsInfo = 未定!;
        }

        函数 setWriter(output: 输出文本作者_): 无值 {
            writer = output;
        }

        函数 setSourceFile(源文件: 源文件_) {
            currentSourceFile = 源文件;
            currentText = currentSourceFile.文本;
            currentLineMap = 获取行开始(currentSourceFile);
            detachedCommentsInfo = 未定!;
        }

        函数 hasDetachedComments(首位: 数字) {
            返回 detachedCommentsInfo !== 未定 && 最后或未定义(detachedCommentsInfo)!.nodePos === 首位;
        }

        函数 forEachLeadingCommentWithoutDetachedComments(cb: (commentPos: 数字, commentEnd: 数字, 种类: 语法_, 有尾随新行: 真假, rangePos: 数字) => 无值) {
            // get the leading 注释组 from detachedPos
            常量 首位 = 最后或未定义(detachedCommentsInfo)!.detachedCommentEndPos;
            如果 (detachedCommentsInfo.长度 - 1) {
                detachedCommentsInfo.弹出();
            }
            否则 {
                detachedCommentsInfo = 未定!;
            }

            循环前导注释范围(currentText, 首位, cb, /*状态*/ 首位);
        }

        函数 emitDetachedCommentsAndUpdateCommentsInfo(range: 文本范围_) {
            常量 currentDetachedCommentInfo = 输出分离注释(currentText, currentLineMap, writer, writeComment, range, newLine, disabled);
            如果 (currentDetachedCommentInfo) {
                如果 (detachedCommentsInfo) {
                    detachedCommentsInfo.压入(currentDetachedCommentInfo);
                }
                否则 {
                    detachedCommentsInfo = [currentDetachedCommentInfo];
                }
            }
        }

        函数 writeComment(文本: 文字, 行词典: 数字[], writer: 输出文本作者_, commentPos: 数字, commentEnd: 数字, newLine: 文字) {
            如果 (emitPos) emitPos(commentPos);
            写注释范围(文本, 行词典, writer, commentPos, commentEnd, newLine);
            如果 (emitPos) emitPos(commentEnd);
        }
    }
}